﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using System.IO;

using MEFedMVVM.ViewModelLocator;
using Cinch;
using System.Configuration;
using System.Threading;
using System.Data.Objects.DataClasses;
using System.Data.Objects;
using System.Data;

namespace Anata.Client
{

    /// <summary>
    /// Runtime implementation of the 
    /// Data service used by the <c>ImageLoaderViewModel</c> to obtain data
    /// </summary>
    [PartCreationPolicy(CreationPolicy.NonShared)]
    [ExportService(ServiceType.Runtime, typeof(IKaryawanProvider))]
    public class KaryawanProvider : IKaryawanProvider
    {
        #region Data
        private BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>> multiFetchTVMBgWorker =
            new BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>>();
        private BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel> singleUpdateTVMBgWorker =
            new BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel>();
        private BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> singleUpdateVMBgWorker =
            new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
        #endregion

        #region Data [NEW]
        private BackgroundTaskManager<int, List<SimpleKaryawanViewModel>> multiFetchSVMBgWorker =
            new BackgroundTaskManager<int, List<SimpleKaryawanViewModel>>();
        private BackgroundTaskManager<ComplexKaryawanViewModel, ComplexKaryawanViewModel> singleUpdateCVMBgWorker =
            new BackgroundTaskManager<ComplexKaryawanViewModel, ComplexKaryawanViewModel>();
        #endregion

        #region PublicMethods
        public void LazyFetchJadwalKaryawans(int page, Action<List<KaryawanThumbnailViewModel>> callback)
        {
            BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>> bgWorker = null;
            if (multiFetchTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>>();
            }
            else
            {
                bgWorker = multiFetchTVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return FetchJadwalKTVMsInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = page;
            bgWorker.RunBackgroundTask();
        }
        public void LazyLoadJadwalKaryawan(KaryawanThumbnailViewModel ktvm, Action<KaryawanThumbnailViewModel> callback)
        {
            BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel> bgWorker = null;
            if (singleUpdateTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel>();
            }
            else
            {
                bgWorker = singleUpdateTVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return LoadJadwalKTVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = ktvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazySaveJadwalKaryawan(KaryawanThumbnailViewModel ktvm, Action<KaryawanThumbnailViewModel> callback)
        {
            BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel> bgWorker = null;
            if (singleUpdateTVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel>();
            }
            else
            {
                bgWorker = singleUpdateTVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return SaveJadwalKTVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = ktvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazyLoadKaryawan(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return LoadKaryawanVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazySaveKaryawan(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return SaveKaryawanVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazyLoadKehadiranTerakhir(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return LoadKehadiranTerakhirVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazySaveKehadiranTerakhir(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return SaveKehadiranTerakhirVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazyLoadJadwalKaryawan(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return LoadJadwalKVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        public void LazySaveJadwalKaryawan(KaryawanViewModel tvm, Action<KaryawanViewModel> callback)
        {
            BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> bgWorker = null;
            if (singleUpdateVMBgWorker.TaskFunc != null)
            {
                bgWorker = new BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel>();
            }
            else
            {
                bgWorker = singleUpdateVMBgWorker;
            }

            bgWorker.TaskFunc = (argument) =>
            {
                return SaveJadwalKVMInternal(argument);
            };

            bgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            bgWorker.WorkerArgument = tvm;
            bgWorker.RunBackgroundTask();
        }
        #endregion

        #region PublicMethods [NEW]
        public void LazyFetchKaryawans(int page, Action<List<SimpleKaryawanViewModel>> callback)
        {
            multiFetchSVMBgWorker.TaskFunc = (argument) =>
            {
                return FetchKaryawansInternal(argument);
            };

            multiFetchSVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            multiFetchSVMBgWorker.WorkerArgument = page;
            multiFetchSVMBgWorker.RunBackgroundTask();
        }
        public void LazyLoadCompleteKaryawan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return LoadCompleteKaryawanInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazyLoadKaryawan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return LoadKaryawanInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazyLoadKaryawanLayanan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return LoadKaryawanLayananInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazyLoadKaryawanProduk(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return LoadKaryawanProdukInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazyLoadKaryawanAturanLembur(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return LoadKaryawanAturanLemburInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazySaveCompleteKaryawan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return SaveCompleteKaryawanInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazySaveKaryawan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return SaveKaryawanInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazySaveKaryawanLayanan(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return SaveKaryawanLayananInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazySaveKaryawanProduk(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return SaveKaryawanProdukInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        public void LazySaveKaryawanAturanLembur(ComplexKaryawanViewModel ckvm, Action<ComplexKaryawanViewModel> callback)
        {
            singleUpdateCVMBgWorker.TaskFunc = (argument) =>
            {
                return SaveKaryawanAturanLemburInternal(argument);
            };

            singleUpdateCVMBgWorker.CompletionAction = (result) =>
            {
                callback(result);
            };

            singleUpdateCVMBgWorker.WorkerArgument = ckvm;
            singleUpdateCVMBgWorker.RunBackgroundTask();
        }
        #endregion

        #region PublicProperties
        /// <summary>
        /// To allow this class to be unit tested stand alone
        /// See CinchV1 articles about Unit Testing for this
        /// Or comments in Cinch BackgroundTaskManager<T> class
        /// </summary>
        public BackgroundTaskManager<int, List<KaryawanThumbnailViewModel>> MultiFetchTVMBgWorker
        {
            get { return multiFetchTVMBgWorker; }
        }
        public BackgroundTaskManager<KaryawanThumbnailViewModel, KaryawanThumbnailViewModel> SingleUpdateTVMBgWorker
        {
            get { return singleUpdateTVMBgWorker; }
        }
        public BackgroundTaskManager<KaryawanViewModel, KaryawanViewModel> SingleUpdateVMBgWorker
        {
            get { return singleUpdateVMBgWorker; }
        }
        /*
        public BackgroundTaskManager<int, bool> ProcessBgWorker
        {
            get { return processBgWorker; }
        }*/
        #endregion

        #region Private Methods
        private List<KaryawanThumbnailViewModel> FetchJadwalKTVMsInternal(int page)
        {
            List<KaryawanThumbnailViewModel> retval = new List<KaryawanThumbnailViewModel>();
            KaryawanThumbnailViewModel tempKTVM = null;
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from karyawan in context.Karyawan
                                join transaksiLayanan in context.TransaksiLayanan.Where(tl => tl.WaktuSelesai == null)
                                    on karyawan.IdKaryawan equals transaksiLayanan.IdKaryawan into j1
                                from j2 in j1.DefaultIfEmpty()
                                group j2 by karyawan into grouped
                                select grouped;
                    foreach (var karyawan in query.OrderByDescending(g => g.Count()).ThenBy(g => g.Key.Nama).ToList()
                        .Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        tempKTVM = new KaryawanThumbnailViewModel();
                        tempKTVM.IdKaryawan = karyawan.Key.IdKaryawan;
                        tempKTVM.Nama = karyawan.Key.Nama;
                        tempKTVM.Alamat = karyawan.Key.Alamat;
                        tempKTVM.NoTelepon = karyawan.Key.NoTelepon;
                        tempKTVM.TanggalKeluar = karyawan.Key.TanggalKeluar;

                        KaryawanLayananThumbnailViewModel tempKLTVM = null;
                        foreach (var karyawanLayanan in karyawan.Key.KaryawanLayanan)
                        {
                            tempKLTVM = new KaryawanLayananThumbnailViewModel();
                            tempKLTVM.IdKaryawan = karyawanLayanan.IdKaryawan;
                            tempKLTVM.IdLayanan = karyawanLayanan.IdLayanan;
                            tempKLTVM.NamaLayanan = karyawanLayanan.Layanan.Nama;
                            tempKTVM.KaryawanLayanans.Add(tempKLTVM);
                        }

                        //kehadiran terakhir hari ini, filtered kehadiran
                        try
                        {
                            KaryawanKehadiran kehadiranTerakhir = karyawan.Key.KaryawanKehadiran
                                .Where(kk => (kk.WaktuMasuk.Value.Date == DateTime.Today) && (kk.WaktuKeluar == null))
                                .OrderByDescending(kk => kk.WaktuMasuk).FirstOrDefault();
                            if (kehadiranTerakhir != null)
                            {
                                tempKTVM.KehadiranTerakhir = new KaryawanKehadiranThumbnailViewModel();
                                tempKTVM.KehadiranTerakhir.IdKaryawanKehadiran = kehadiranTerakhir.IdKaryawanKehadiran;
                                tempKTVM.KehadiranTerakhir.IdKaryawan = kehadiranTerakhir.IdKaryawan;
                                tempKTVM.KehadiranTerakhir.NamaKaryawan = kehadiranTerakhir.Karyawan.Nama;
                                tempKTVM.KehadiranTerakhir.WaktuMasuk = kehadiranTerakhir.WaktuMasuk;
                                tempKTVM.KehadiranTerakhir.WaktuKeluar = kehadiranTerakhir.WaktuKeluar;
                            }
                        }
                        catch (Exception) {}

                        //jadwal, filtered transaksi layanan
                        TransaksiLayananThumbnailViewModel tempTLTVM = null;
                        try
                        {
                            foreach (var transaksiLayanan in karyawan
                                .OrderBy(tl => tl.WaktuMulai == null)
                                .ThenBy(tl => tl.WaktuMulai)
                                .ThenBy(tl => tl.WaktuTunggu == null)
                                .ThenBy(tl => tl.WaktuTunggu)
                                .ThenBy(tl => tl.WaktuBuat))
                            {
                                tempTLTVM = new TransaksiLayananThumbnailViewModel();
                                tempTLTVM.IdTransaksiLayanan = transaksiLayanan.IdTransaksiLayanan;
                                tempTLTVM.NamaLayanan = transaksiLayanan.Layanan.Nama;
                                tempTLTVM.NamaKonsumen = transaksiLayanan.Transaksi.Konsumen.Nama;
                                tempTLTVM.WaktuBuat = transaksiLayanan.WaktuBuat;
                                tempTLTVM.WaktuTunggu = transaksiLayanan.WaktuTunggu;
                                tempTLTVM.WaktuMulai = transaksiLayanan.WaktuMulai;
                                tempTLTVM.WaktuSelesai = transaksiLayanan.WaktuSelesai;
                                tempTLTVM.IsBatal = transaksiLayanan.IsBatal;
                                tempTLTVM.PreviousStatusTransaksiLayanan = tempTLTVM.StatusTransaksiLayanan;
                                tempKTVM.JadwalKaryawans.Add(tempTLTVM);
                            }
                        }
                        catch (Exception) {}

                        retval.Add(tempKTVM);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanThumbnailViewModel LoadJadwalKTVMInternal (KaryawanThumbnailViewModel ktvm)
        {
            KaryawanThumbnailViewModel retval = ktvm;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ktvm.IdKaryawan
                                          select karyawan).First();

                    ktvm.JadwalKaryawans.Clear();
                    TransaksiLayananThumbnailViewModel tltvm = null;
                    foreach (var tl in originalK.TransaksiLayanan
                        .Where(tl => tl.WaktuSelesai == null)
                        .OrderBy(tl => tl.WaktuMulai == null)
                        .ThenBy(tl => tl.WaktuMulai)
                        .ThenBy(tl => tl.WaktuTunggu == null)
                        .ThenBy(tl => tl.WaktuTunggu)
                        .ThenBy(tl => tl.WaktuBuat))
                    {
                        tltvm = new TransaksiLayananThumbnailViewModel();
                        tltvm.IdTransaksiLayanan = tl.IdTransaksiLayanan;
                        tltvm.NamaLayanan = tl.Layanan.Nama;
                        tltvm.NamaKonsumen = tl.Transaksi.Konsumen.Nama;
                        tltvm.WaktuBuat = tl.WaktuBuat;
                        tltvm.WaktuTunggu = tl.WaktuTunggu;
                        tltvm.WaktuMulai = tl.WaktuMulai;
                        tltvm.WaktuSelesai = tl.WaktuSelesai;
                        tltvm.IsBatal = tl.IsBatal;
                        tltvm.PreviousStatusTransaksiLayanan = tltvm.StatusTransaksiLayanan;
                        ktvm.JadwalKaryawans.Add(tltvm);
                    }
                    retval = ktvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanThumbnailViewModel SaveJadwalKTVMInternal (KaryawanThumbnailViewModel ktvm)
        {
            KaryawanThumbnailViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from k in context.Karyawan
                                          where k.IdKaryawan == ktvm.IdKaryawan
                                          select k).First();

                    TransaksiLayanan originalTL = null;
                    foreach (TransaksiLayananThumbnailViewModel tltvm in ktvm.JadwalKaryawans)
                    {
                        originalTL = (from tl in originalK.TransaksiLayanan
                                      where tl.IdTransaksiLayanan == tltvm.IdTransaksiLayanan
                                      select tl).First();
                        originalTL.IdKaryawan = tltvm.IdKaryawan;
                        originalTL.WaktuBuat = tltvm.WaktuBuat;
                        originalTL.WaktuTunggu = tltvm.WaktuTunggu;
                        originalTL.WaktuMulai = tltvm.WaktuMulai;
                        originalTL.WaktuSelesai = tltvm.WaktuSelesai;
                        originalTL.IsBatal = tltvm.IsBatal;

                        if (originalTL.EntityState == EntityState.Modified)
                        {
                            //originalTL.IdUser = SessionController.Instance.LoggedUserId;
                            originalTL.LastUpdated = DateTime.Now;
                        }
                    }
                    retval = ktvm;
                    context.SaveChanges();
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanViewModel LoadKaryawanVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == kvm.IdKaryawan.DataValue
                                          select karyawan).First();
                    kvm.Nama.DataValue = originalK.Nama;
                    kvm.Alamat.DataValue = originalK.Alamat;
                    kvm.NoTelepon.DataValue = originalK.NoTelepon;
                    kvm.NoKTP.DataValue = originalK.NoKTP;
                    kvm.JenisKelamin.DataValue = originalK.JenisKelamin.Nama;
                    kvm.TanggalLahir.DataValue = originalK.TanggalLahir;
                    kvm.Status.DataValue = originalK.Status.Nama;
                    kvm.Agama.DataValue = originalK.Agama.Nama;
                    kvm.GolDarah.DataValue = originalK.GolonganDarah.Nama;
                    kvm.TanggalMasuk.DataValue = originalK.TanggalMasuk;
                    kvm.TanggalKeluar.DataValue = originalK.TanggalKeluar;

                    kvm.KaryawanLayanans.Clear();
                    KaryawanLayananViewModel klvm = null;
                    foreach (var kl in originalK.KaryawanLayanan)
                    {
                        klvm = kvm.ForceCreateChildKaryawanLayananVM();
                        klvm.IdKaryawan.DataValue = kl.IdKaryawan;
                        klvm.IdLayanan.DataValue = kl.IdLayanan;
                        klvm.NamaLayanan = kl.Layanan.Nama;
                        kvm.KaryawanLayanans.Add(klvm);
                    }
                    retval = kvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanViewModel SaveKaryawanVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = null;
                    List<int> originalKLs = new List<int>();

                    if (kvm.IdKaryawan.DataValue != 0)
                    {
                        originalK = (from k in context.Karyawan
                                     where k.IdKaryawan == kvm.IdKaryawan.DataValue
                                     select k).First();
                        foreach (var kl in originalK.KaryawanLayanan)
                        {
                            originalKLs.Add(kl.IdLayanan);
                        }
                    }
                    else
                    {
                        originalK = context.Karyawan.CreateObject();
                        context.Karyawan.AddObject(originalK);
                        //TODO: Id Cabang & User
                        //originalTransaksi.IdUser = SessionController.Instance.LoggedUserId;
                        originalK.LastUpdated = DateTime.Now;
                    }
                    originalK.Nama = kvm.Nama.DataValue;
                    originalK.Alamat = kvm.Alamat.DataValue;
                    originalK.NoTelepon = kvm.NoTelepon.DataValue;
                    originalK.NoKTP = kvm.NoKTP.DataValue;
                    //originalK.JenisKelamin = kvm.JenisKelamin.DataValue;
                    originalK.TanggalLahir = kvm.TanggalLahir.DataValue;
                    //originalK.Status = kvm.Status.DataValue;
                    //originalK.Agama = kvm.Agama.DataValue;
                    //originalK.GolonganDarah = kvm.GolDarah.DataValue;
                    originalK.TanggalMasuk = kvm.TanggalMasuk.DataValue;
                    originalK.TanggalKeluar = kvm.TanggalKeluar.DataValue;

                    if (originalK.EntityState == EntityState.Modified)
                    {
                        //originalK.IdUser = SessionController.Instance.LoggedUserId;
                        originalK.LastUpdated = DateTime.Now;
                    }

                    KaryawanLayanan originalKL = null;
                    foreach (KaryawanLayananViewModel klvm in kvm.KaryawanLayanans)
                    {
                        if (originalKLs.Remove(klvm.IdLayanan.DataValue))
                        {
                            originalKL = (from kl in originalK.KaryawanLayanan
                                          where kl.IdLayanan == klvm.IdLayanan.DataValue
                                          select kl).First();
                        }
                        else
                        {
                            originalKL = context.KaryawanLayanan.CreateObject();
                            context.KaryawanLayanan.AddObject(originalKL);
                            originalK.KaryawanLayanan.Add(originalKL);
                            //originalKL .IdUser = SessionController.Instance.LoggedUserId;
                            originalKL.LastUpdated = DateTime.Now;
                        }
                        originalKL.IdLayanan = klvm.IdLayanan.DataValue;

                        if (originalKL.EntityState == EntityState.Modified)
                        {
                            //originalKL.IdUser = SessionController.Instance.LoggedUserId;
                            originalKL.LastUpdated = DateTime.Now;
                        }
                    }
                    //clearing
                    foreach (int removedId in originalKLs)
                    {
                        context.KaryawanLayanan.DeleteObject(
                            originalK.KaryawanLayanan.First(
                                kl => kl.IdLayanan == removedId));
                    }
                    retval = kvm;
                    context.SaveChanges();
                }
            }
            catch (Exception) { }
            return retval;

        }
        private KaryawanViewModel LoadKehadiranTerakhirVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == kvm.IdKaryawan.DataValue
                                          select karyawan).First();

                    KaryawanKehadiran originalKK = null;
                    try
                    {
                        originalKK = (from kk in originalK.KaryawanKehadiran
                                      where kk.WaktuMasuk.Value.Date == DateTime.Today
                                      where !kk.WaktuKeluar.HasValue
                                      orderby kk.WaktuMasuk descending
                                      select kk).FirstOrDefault();
                        kvm.KehadiranTerakhir = kvm.ForceCreateChildKaryawanKehadiranVM();
                        kvm.KehadiranTerakhir.IdKaryawanKehadiran.DataValue = originalKK.IdKaryawanKehadiran;
                        kvm.KehadiranTerakhir.IdKaryawan.DataValue = originalKK.IdKaryawan;
                        kvm.KehadiranTerakhir.NamaKaryawan = originalKK.Karyawan.Nama;
                        kvm.KehadiranTerakhir.WaktuMasuk.DataValue = originalKK.WaktuMasuk;
                        kvm.KehadiranTerakhir.WaktuKeluar.DataValue = originalKK.WaktuKeluar;
                    }
                    catch (Exception) { }

                    retval = kvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanViewModel SaveKehadiranTerakhirVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from k in context.Karyawan
                                          where k.IdKaryawan == kvm.IdKaryawan.DataValue
                                          select k).First();

                    KaryawanKehadiranViewModel kkvm = kvm.KehadiranTerakhir;

                    KaryawanKehadiran originalKK = null;
                    if (kkvm.IdKaryawanKehadiran.DataValue != 0)
                    {
                        originalKK = (from kk in originalK.KaryawanKehadiran
                                      where kk.IdKaryawanKehadiran == kkvm.IdKaryawanKehadiran.DataValue
                                      select kk).FirstOrDefault();
                    }
                    else
                    {
                        originalKK = context.KaryawanKehadiran.CreateObject();
                        context.KaryawanKehadiran.AddObject(originalKK);
                        originalK.KaryawanKehadiran.Add(originalKK);
                        //originalKK .IdUser = SessionController.Instance.LoggedUserId;
                        originalKK.LastUpdated = DateTime.Now;
                    }
                    originalKK.WaktuMasuk = kkvm.WaktuMasuk.DataValue;
                    originalKK.WaktuKeluar = kkvm.WaktuKeluar.DataValue;

                    if (originalKK.EntityState == EntityState.Modified)
                    {
                        //originalKL.IdUser = SessionController.Instance.LoggedUserId;
                        originalKK.LastUpdated = DateTime.Now;
                    }

                    context.SaveChanges();

                    //refresh kehadiran terakhir
                    LoadKehadiranTerakhirVMInternal(kvm);

                    retval = kvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanViewModel LoadJadwalKVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == kvm.IdKaryawan.DataValue
                                          select karyawan).First();

                    SynchJadwalLayananToKVM(originalK, kvm);
                    retval = kvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private KaryawanViewModel SaveJadwalKVMInternal(KaryawanViewModel kvm)
        {
            KaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from k in context.Karyawan
                                          where k.IdKaryawan == kvm.IdKaryawan.DataValue
                                          select k).First();

                    TransaksiLayanan originalTL = null;
                    foreach (TransaksiLayananViewModel tlvm in kvm.JadwalKaryawans)
                    {
                        originalTL = (from tl in originalK.TransaksiLayanan
                                      where tl.IdTransaksiLayanan == tlvm.IdTransaksiLayanan.DataValue
                                      select tl).First();
                        originalTL.IdKaryawan = tlvm.IdKaryawan.DataValue;
                        originalTL.WaktuBuat = tlvm.WaktuBuat.DataValue;
                        originalTL.WaktuTunggu = tlvm.WaktuTunggu.DataValue;
                        originalTL.WaktuMulai = tlvm.WaktuMulai.DataValue;
                        originalTL.WaktuSelesai = tlvm.WaktuSelesai.DataValue;
                        originalTL.IsBatal = tlvm.IsBatal.DataValue;

                        if (originalTL.EntityState == EntityState.Modified)
                        {
                            //originalTL.IdUser = SessionController.Instance.LoggedUserId;
                            originalTL.LastUpdated = DateTime.Now;
                        }
                    }
                    context.SaveChanges();

                    SynchJadwalLayananToKVM(originalK, kvm);
                    retval = kvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        #endregion

        #region PrivateMethods [NEW]
        private List<SimpleKaryawanViewModel> FetchKaryawansInternal(int page)
        {
            List<SimpleKaryawanViewModel> retval = new List<SimpleKaryawanViewModel>();
            try
            {
                int pageSize = Int32.Parse(ConfigurationManager.AppSettings["LazyLoadPageSize"].ToString());
                using (AnataEntities context = new AnataEntities())
                {
                    var query = from karyawan in context.Karyawan
                                orderby karyawan.Nama
                                select karyawan;
                    SimpleKaryawanViewModel skvm = null;
                    foreach (var karyawan in query.Skip(page * pageSize).Take(pageSize).ToList())
                    {
                        skvm = new SimpleKaryawanViewModel();
                        skvm.Karyawan = karyawan;
                        skvm.JenisKelamin = karyawan.JenisKelamin;
                        skvm.Status = karyawan.Status;
                        skvm.Agama = karyawan.Agama;
                        skvm.GolonganDarah = karyawan.GolonganDarah;
                        retval.Add(skvm);
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }

        private ComplexKaryawanViewModel LoadCompleteKaryawanInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ckvm.LoadedKaryawan.IdKaryawan
                                          select karyawan).First();
                    SynchCKVMFromKaryawan(originalK, ckvm, context);
                    SynchCKVMFromKaryawanLayanan(originalK, ckvm, context);
                    SynchCKVMFromKaryawanProduk(originalK, ckvm, context);
                    SynchCKVMFromKaryawanAturanLembur(originalK, ckvm, context);
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel LoadKaryawanInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ckvm.LoadedKaryawan.IdKaryawan
                                          select karyawan).First();
                    SynchCKVMFromKaryawan(originalK, ckvm, context);
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel LoadKaryawanLayananInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ckvm.LoadedKaryawan.IdKaryawan
                                          select karyawan).First();
                    SynchCKVMFromKaryawanLayanan(originalK, ckvm, context);
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel LoadKaryawanProdukInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ckvm.LoadedKaryawan.IdKaryawan
                                          select karyawan).First();
                    SynchCKVMFromKaryawanProduk(originalK, ckvm, context);
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel LoadKaryawanAturanLemburInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = (from karyawan in context.Karyawan
                                          where karyawan.IdKaryawan == ckvm.LoadedKaryawan.IdKaryawan
                                          select karyawan).First();
                    SynchCKVMFromKaryawanAturanLembur(originalK, ckvm, context);
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }

        private ComplexKaryawanViewModel SaveCompleteKaryawanInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = CreateOrLoadKaryawan(ckvm, context);
                    SynchCKVMToKaryawan(originalK, ckvm, context);
                    SynchCKVMToKaryawanLayanan(originalK, ckvm, context);
                    SynchCKVMToKaryawanProduk(originalK, ckvm, context);
                    SynchCKVMToKaryawanAturanLembur(originalK, ckvm, context);
                    context.SaveChanges();
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel SaveKaryawanInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = CreateOrLoadKaryawan(ckvm, context);
                    SynchCKVMToKaryawan(originalK, ckvm, context);
                    context.SaveChanges();
                    retval = ckvm;
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel SaveKaryawanLayananInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = null;
                    if (ckvm.IdKaryawan.DataValue != 0)
                    {
                        originalK = (from k in context.Karyawan
                                     where k.IdKaryawan == ckvm.IdKaryawan.DataValue
                                     select k).First();
                        SynchCKVMToKaryawanLayanan(originalK, ckvm, context);
                        context.SaveChanges();
                        retval = ckvm;
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel SaveKaryawanProdukInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = null;
                    if (ckvm.IdKaryawan.DataValue != 0)
                    {
                        originalK = (from k in context.Karyawan
                                     where k.IdKaryawan == ckvm.IdKaryawan.DataValue
                                     select k).First();
                        SynchCKVMToKaryawanProduk(originalK, ckvm, context);
                        context.SaveChanges();
                        retval = ckvm;
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        private ComplexKaryawanViewModel SaveKaryawanAturanLemburInternal(ComplexKaryawanViewModel ckvm)
        {
            ComplexKaryawanViewModel retval = null;
            try
            {
                using (AnataEntities context = new AnataEntities())
                {
                    Karyawan originalK = null;
                    if (ckvm.IdKaryawan.DataValue != 0)
                    {
                        originalK = (from k in context.Karyawan
                                     where k.IdKaryawan == ckvm.IdKaryawan.DataValue
                                     select k).First();
                        SynchCKVMToKaryawanAturanLembur(originalK, ckvm, context);
                        context.SaveChanges();
                        retval = ckvm;
                    }
                }
            }
            catch (Exception) { }
            return retval;
        }
        #endregion

        #region Initializer
        private Karyawan CreateOrLoadKaryawan(ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            Karyawan originalK = null;
            if (ckvm.IdKaryawan.DataValue != 0)
            {
                originalK = (from k in context.Karyawan
                             where k.IdKaryawan == ckvm.IdKaryawan.DataValue
                             select k).First();
            }
            else
            {
                originalK = context.Karyawan.CreateObject();
                context.Karyawan.AddObject(originalK);
                //TODO: Id Cabang & User
                //originalTransaksi.IdUser = SessionController.Instance.LoggedUserId;
                originalK.LastUpdated = DateTime.Now;
            }
            return originalK;
        }
        #endregion

        #region Synchronizer
        public static void SynchJadwalLayananToKVM(Karyawan originalK, KaryawanViewModel kvm)
        {
            kvm.JadwalKaryawans.Clear();
            TransaksiLayananViewModel tlvm = null;
            foreach (var tl in originalK.TransaksiLayanan
                .Where(tl => tl.WaktuSelesai == null)
                .OrderBy(tl => tl.WaktuMulai == null)
                .ThenBy(tl => tl.WaktuMulai)
                .ThenBy(tl => tl.WaktuTunggu == null)
                .ThenBy(tl => tl.WaktuTunggu)
                .ThenBy(tl => tl.WaktuBuat))
            {
                tlvm = kvm.ForceCreateChildTransaksiLayananVM();
                tlvm.IdTransaksiLayanan.DataValue = tl.IdTransaksiLayanan;
                tlvm.IdTransaksi.DataValue = tl.IdTransaksi;
                tlvm.IdKaryawan.DataValue = tl.IdKaryawan;
                tlvm.IdLayanan.DataValue = tl.IdLayanan;
                tlvm.NamaLayanan = tl.Layanan.Nama;
                tlvm.NamaKonsumen = tl.Transaksi.Konsumen.Nama;
                tlvm.WaktuBuat.DataValue = tl.WaktuBuat;
                tlvm.WaktuTunggu.DataValue = tl.WaktuTunggu;
                tlvm.WaktuMulai.DataValue = tl.WaktuMulai;
                tlvm.WaktuSelesai.DataValue = tl.WaktuSelesai;
                tlvm.IsBatal.DataValue = tl.IsBatal;
                tlvm.PreviousStatusTransaksiLayanan = tlvm.StatusTransaksiLayanan;
                kvm.JadwalKaryawans.Add(tlvm);
            }
        }
        #endregion

        #region Synchronizer [New]
        private void SynchCKVMToKaryawan(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            originalK.NIP = ckvm.Nip.DataValue;
            originalK.Nama = ckvm.Nama.DataValue;
            originalK.Alamat = ckvm.Alamat.DataValue;
            originalK.NoTelepon = ckvm.NoTelepon.DataValue;
            originalK.NoKTP = ckvm.NoKTP.DataValue;
            originalK.TanggalLahir = ckvm.TanggalLahir.DataValue;
            originalK.IdJenisKelamin = ckvm.IdJenisKelamin.DataValue;
            originalK.IdStatus = ckvm.IdStatus.DataValue;
            originalK.IdAgama = ckvm.IdAgama.DataValue;
            originalK.IdGolonganDarah = ckvm.IdGolonganDarah.DataValue;
            originalK.TanggalMasuk = ckvm.TanggalMasuk.DataValue;
            originalK.TanggalKeluar = ckvm.TanggalKeluar.DataValue;
            originalK.IsHonorer = ckvm.IsHonorer.DataValue;
            originalK.HariEfektif = ckvm.HariEfektif.DataValue;
            originalK.GajiHarian = ckvm.NominalGajiHarian.DataValue;
            originalK.Tunjangan = ckvm.NominalTunjangan.DataValue;
            originalK.IdCabang = ckvm.IdCabang.DataValue;

            if (originalK.EntityState == EntityState.Modified)
            {
                //originalK.IdUser = SessionController.Instance.LoggedUserId;
                originalK.LastUpdated = DateTime.Now;
            }
        }
        private void SynchCKVMToKaryawanLayanan(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            KaryawanLayanan originalKL = null;
            foreach (ComplexKaryawanLayananViewModel cklvm in ckvm.KaryawanLayanans)
            {
                if (cklvm.IdKaryawan.DataValue != 0 && cklvm.IdLayanan.DataValue != 0)
                {
                    originalKL = (from kl in originalK.KaryawanLayanan
                                  where kl.IdLayanan == cklvm.IdLayanan.DataValue
                                  select kl).First();
                }
                else
                {
                    originalKL = context.KaryawanLayanan.CreateObject();
                    context.KaryawanLayanan.AddObject(originalKL);
                    originalK.KaryawanLayanan.Add(originalKL);
                    //originalKL .IdUser = SessionController.Instance.LoggedUserId;
                    originalKL.LastUpdated = DateTime.Now;
                }

                if (!cklvm.IsDeleted.DataValue)
                {
                    originalKL.IdLayanan = cklvm.IdLayanan.DataValue;
                    originalKL.IsKomisiPersentase = cklvm.IsKomisiPersentase.DataValue;
                    originalKL.Komisi = cklvm.Komisi.DataValue;
                    originalKL.PersentaseKomisi = (float)cklvm.PersentaseKomisi.DataValue;
                    originalKL.Target = cklvm.Target.DataValue;

                    if (originalKL.EntityState == EntityState.Modified)
                    {
                        //originalKL.IdUser = SessionController.Instance.LoggedUserId;
                        originalKL.LastUpdated = DateTime.Now;
                    }
                }
                else
                {
                    context.KaryawanLayanan.DeleteObject(
                        originalK.KaryawanLayanan.First(
                            kl => kl.IdLayanan == cklvm.IdLayanan.DataValue));
                }
            }
        }
        private void SynchCKVMToKaryawanProduk(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            KaryawanProduk originalKP = null;
            foreach (ComplexKaryawanProdukViewModel ckpvm in ckvm.KaryawanProduks)
            {
                if (ckpvm.IdKaryawan.DataValue != 0 && ckpvm.IdKategoriStok.DataValue != 0)
                {
                    originalKP = (from kp in originalK.KaryawanProduk
                                  where kp.IdKategoriStok == ckpvm.IdKategoriStok.DataValue
                                  select kp).First();
                }
                else
                {
                    originalKP = context.KaryawanProduk.CreateObject();
                    context.KaryawanProduk.AddObject(originalKP);
                    originalK.KaryawanProduk.Add(originalKP);
                    //originalKP.IdUser = SessionController.Instance.LoggedUserId;
                    originalKP.LastUpdated = DateTime.Now;
                }

                if (!ckpvm.IsDeleted.DataValue)
                {
                    originalKP.IdKategoriStok = ckpvm.IdKategoriStok.DataValue;
                    originalKP.IsKomisiPersentase = ckpvm.IsKomisiPersentase.DataValue;
                    originalKP.Komisi = ckpvm.Komisi.DataValue;
                    originalKP.KomisiPersentase = (float)ckpvm.PersentaseKomisi.DataValue;
                    originalKP.Target = ckpvm.Target.DataValue;

                    if (originalKP.EntityState == EntityState.Modified)
                    {
                        //originalKP.IdUser = SessionController.Instance.LoggedUserId;
                        originalKP.LastUpdated = DateTime.Now;
                    }
                }
                else
                {
                    context.KaryawanProduk.DeleteObject(
                        originalK.KaryawanProduk.First(
                            kl => kl.IdKategoriStok == ckpvm.IdKategoriStok.DataValue));
                }
            }
        }
        private void SynchCKVMToKaryawanAturanLembur(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            KaryawanAturanLembur originalKA = null;
            foreach (ComplexKaryawanAturanLemburViewModel ckavm in ckvm.KaryawanAturanLemburs)
            {
                if (ckavm.IdKaryawanAturanLembur.DataValue != 0)
                {
                    originalKA = (from ka in originalK.KaryawanAturanLembur
                                  where ka.IdKaryawanAturanLembur == ckavm.IdKaryawanAturanLembur.DataValue
                                  select ka).First();
                }
                else
                {
                    originalKA = context.KaryawanAturanLembur.CreateObject();
                    context.KaryawanAturanLembur.AddObject(originalKA);
                    originalK.KaryawanAturanLembur.Add(originalKA);
                    //originalKA.IdUser = SessionController.Instance.LoggedUserId;
                    originalKA.LastUpdated = DateTime.Now;
                }

                if (!ckavm.IsDeleted.DataValue)
                {
                    originalKA.MenitMinimal = ckavm.MenitMinimal.DataValue;
                    originalKA.NominalLembur = ckavm.NominalLembur.DataValue;

                    if (originalKA.EntityState == EntityState.Modified)
                    {
                        //originalKA.IdUser = SessionController.Instance.LoggedUserId;
                        originalKA.LastUpdated = DateTime.Now;
                    }
                }
                else
                {
                    context.KaryawanAturanLembur.DeleteObject(
                        originalK.KaryawanAturanLembur.First(
                            ka => ka.IdKaryawanAturanLembur == ckavm.IdKaryawanAturanLembur.DataValue));
                }
            }
        }

        private void SynchCKVMFromKaryawan(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            ckvm.LoadedKaryawan = originalK;
        }
        private void SynchCKVMFromKaryawanLayanan(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            ComplexKaryawanLayananViewModel cklvm = null;
            foreach (var originalKL in originalK.KaryawanLayanan)
            {
                cklvm = ckvm.ForceCreateChildKaryawanLayananVM(originalKL, originalKL.Layanan);
            }
        }
        private void SynchCKVMFromKaryawanProduk(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            ComplexKaryawanProdukViewModel ckpvm = null;
            foreach (var originalKP in originalK.KaryawanProduk)
            {
                ckpvm = ckvm.ForceCreateChildKaryawanProdukVM(originalKP, originalKP.KategoriStok);
            }
        }
        private void SynchCKVMFromKaryawanAturanLembur(Karyawan originalK, ComplexKaryawanViewModel ckvm, AnataEntities context)
        {
            ComplexKaryawanAturanLemburViewModel ckavm = null;
            foreach (var originalKA in originalK.KaryawanAturanLembur)
            {
                ckavm = ckvm.ForceCreateChildKaryawanAturanLemburVM(originalKA);
            }
        }
        #endregion
    }
}
